package gui.data;

import model.ParseConfig;
import gui.MainFrame;

import javax.swing.*;

import model.db.ConnectionDescriptor;
import model.db.DefaultConnection;

import java.awt.*;
import java.awt.event.*;
import java.sql.SQLException;
import java.util.*;
import java.io.File;

/**
 * Klasa za pregledavanje i mijenjanje opcija potrebnih za spajanje na bazu
 * podataka. Nasljeduje JDialog. Korisnik sam upisuje user name i password, 
 * dok ostale opcije dobiva iz parametra options prilikom instanciranja 
 * ConfigDialog komponente.
 * <p>ConfigDialog sadrzi tri tipke: Save, Connect i Cancel. Pomocu Save
 * se spremaju trenutne opcije u datoteku po izboru. Connect sluzi za spajanje
 * na bazu koristenjem trenutnih opcija. Cancel zatvara ConfigDialog.
 * 
 * @author Hrvoje Torbasinovic
 * @version 0.1
 * @see gui.MainFrame
 * @see model.ParseConfig
 * @see model.db.ConnectionDescriptor
 * @see model.db.DefaultConnection
 */
public class ConfigDialog extends JDialog implements ActionListener{
	
	private static final long serialVersionUID = 1L;
	
	private int size;
	private MainFrame parent;
	private JPanel mainPanel;
	private JPanel optionsPanel;
	private JPanel buttonPanel;
	private JTextField usernameField;
	private JPasswordField passwordField;
	private JButton saveButton;
	private JButton connectButton;
	private JButton cancelButton;
	private GridBagLayout gridbag;
	private JLabel[] labels;
	private JTextField[] textFields;
	
	
	/**
	 * Instancira novi ConfigDialog u kojem se nalaze opcije potrebne za 
	 * spajanje na bazu podataka.
	 * 
	 * @param parent komponenta roditelj iz koje je kreiran ConfigDialog
	 * @param options mapa u kojoj se nalaze opcije koje se prikazuju u
	 * ConfigDialogu
	 */
	public ConfigDialog(JFrame parent, LinkedHashMap<String,String> options)
	{
		super(parent, "Connect options", true);
		this.parent = (MainFrame)parent;
		mainPanel = new JPanel();
		mainPanel.setLayout(new BorderLayout(10,10));
		
		optionsPanel = new JPanel();
		buttonPanel = new JPanel();
		
		usernameField = new JTextField("bpadmin");
		passwordField = new JPasswordField("p1234");
		
		gridbag = new GridBagLayout();
		
		optionsPanel.setLayout(gridbag);
		
		addLabelTextRows(options, gridbag, optionsPanel);
		
		optionsPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
		
		saveButton = new JButton("Save");
		saveButton.setActionCommand("save");
		saveButton.addActionListener(this);
		buttonPanel.add(saveButton);
		
		connectButton = new JButton("Connect");
		connectButton.setActionCommand("connect");
		connectButton.addActionListener(this);
		buttonPanel.add(connectButton);
		
		cancelButton = new JButton("Cancel");
		cancelButton.setActionCommand("cancel");
		cancelButton.addActionListener(this);
		buttonPanel.add(cancelButton);
		
		mainPanel.add(optionsPanel, BorderLayout.CENTER);
		mainPanel.add(buttonPanel, BorderLayout.SOUTH);
		
		this.add(mainPanel);
	}
	
	private void addLabelTextRows(LinkedHashMap<String,String> options, GridBagLayout gridbag, JPanel container)
	{
		int i=0;
		size = options.size();
		labels = new JLabel[size];
		textFields = new JTextField[size];
		JLabel usernameLabel = new JLabel("username");
		JLabel passwordLabel = new JLabel("password");
		GridBagConstraints  constraints = new GridBagConstraints();
		
		constraints.anchor = GridBagConstraints.EAST;
		constraints.ipadx = 10;
		constraints.ipady = 15;
		
		constraints.gridwidth = GridBagConstraints.RELATIVE;
		constraints.fill = GridBagConstraints.NONE;
		constraints.weightx = 0.0;
		
		optionsPanel.add(usernameLabel, constraints);
		constraints.gridx = 0;
		constraints.gridy = 1;
		optionsPanel.add(passwordLabel, constraints);
		
		constraints.ipady = 2;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.weightx = 1.0;
		 
		constraints.gridx = 1;
		constraints.gridy = 0;
		optionsPanel.add(usernameField, constraints);
		
		constraints.gridx = 1;
		constraints.gridy = 1;
		optionsPanel.add(passwordField, constraints);
		
		constraints.gridx = 0;
		constraints.gridy = 2;
		optionsPanel.add(new JSeparator(SwingConstants.HORIZONTAL),constraints);
		
		for (String s : options.keySet())
		{
			constraints.gridwidth = GridBagConstraints.RELATIVE;
			constraints.fill = GridBagConstraints.NONE;
			constraints.weightx = 0.0;
			constraints.gridx = 0;
			constraints.gridy = 3 + i;
			constraints.ipady = 15;
			
			labels[i] = new JLabel(s);
			optionsPanel.add(labels[i], constraints);
			
			constraints.ipady = 2;
			constraints.gridwidth = GridBagConstraints.REMAINDER;
			constraints.fill = GridBagConstraints.HORIZONTAL;
			constraints.weightx = 1.0;
			constraints.gridx = 1;
			constraints.gridy = 3 + i;
			
			textFields[i] = new JTextField(options.get(s));
			optionsPanel.add(textFields[i], constraints);
			
			i++;
		}
	}
	
	/**
	 * Dohvaca opcije iz JLabela i JTextFielda u ConfigDialogu, ali ne i
	 * username i password. Koristi se pri spremanju opcija u konfiguracijsku
	 * datoteku
	 * 
	 * @return mapa u kojoj se nalaze opcije 
	 * @see #getAllOptions()
	 */
	public LinkedHashMap<String,String> getOptions()
	{
		LinkedHashMap<String,String> options = new LinkedHashMap<String,String>();
		for (int i = 0; i<size; i++)
		{
			options.put(labels[i].getText(), textFields[i].getText());
		}
		return options;
	}
	
	/**
	 * Dohvaca sve opcije iz JLabela i JTextFielda u ConfigDialogu, 
	 * ukljucujuci i username i password. Koristi se pri spajanju na bazu
	 * 
	 * @return mapa u kojoj se nalaze sve opcije
	 * @see #getOptions()
	 */
	public LinkedHashMap<String,String> getAllOptions()
	{
		LinkedHashMap<String,String> options = this.getOptions();
		options.put("user", usernameField.getText());
		options.put("password", new String(passwordField.getPassword()));
		return options;
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent event)
	{
		String path;
		String akcija = event.getActionCommand();
		
		if (akcija.equals("save"))
		{
			JFileChooser fileChooser = new JFileChooser();
			fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
			int returnVal = fileChooser.showSaveDialog(this);
			if (returnVal == JFileChooser.APPROVE_OPTION)
			{
				path = fileChooser.getSelectedFile().getAbsolutePath();
				File f = new File(path);
				ParseConfig config = new ParseConfig();
				config.save(this.getOptions(), f);
			}
		}
		
		else if (akcija.equals("connect"))
		{
			ConnectionDescriptor cd = new ConnectionDescriptor(this.getAllOptions());
			
			DefaultConnection.setDefaultConnectionDescriptor(cd);
	        
			// punjenje driver-a
	        try 
	        {
	        	cd.loadDriver();
	        }catch (ClassNotFoundException e)
	        {
	        	e.printStackTrace();
	        }
	        
	        // spajanje na bazu
	        try 
	        {
	        	cd.connect();
	        } catch (SQLException e) 
	        {
	        	e.printStackTrace();
	        }
	        if (cd.isConnected())
	        {
	        	parent.generateTree();
	        	this.dispose();    	
	        }
		}
		
		else if (akcija.equals("cancel"))
		{
			this.dispose();
		}
	}
}
